package org.light.shiroauth;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.light.core.LayoutComb;
import org.light.core.ReportComb;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Util;
import org.light.easyuilayouts.widgets.Nav;
import org.light.utils.DomainUtil;
import org.light.utils.StringUtil;

public class ShiroAuthFilterJavaGenerator extends Util{
	protected Domain sampleDomain;

	public Domain getSampleDomain() {
		return sampleDomain;
	}

	public void setSampleDomain(Domain sampleDomain) {
		this.sampleDomain = sampleDomain;
	}
	
	public ShiroAuthFilterJavaGenerator(Domain sampleDomain){
		super();
		this.sampleDomain = sampleDomain;
		this.setPackageToken(sampleDomain.getPackageToken());
		super.fileName = "ShiroAuthFilter.java";
	}
	
	@Override
	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
	}
	
	@Override
	public String generateUtilString() {
		StatementList sList = new StatementList();
		sList.add(new Statement(500L,"package "+this.getPackageToken()+".shiro;"));
		sList.add(new Statement(2000L,0,""));
		sList.add(new Statement(3000L,0,"import java.io.PrintWriter;"));
		sList.add(new Statement(4000L,0,"import java.util.HashMap;"));
		sList.add(new Statement(5000L,0,"import java.util.Map;"));
		sList.add(new Statement(6000L,0,""));
		if ("boot3".equalsIgnoreCase(this.sampleDomain.getTechnicalStack())||"jpa".equalsIgnoreCase(this.sampleDomain.getTechnicalStack())) {
			sList.add(new Statement(7000L,0,"import jakarta.servlet.ServletRequest;"));
			sList.add(new Statement(8000L,0,"import jakarta.servlet.ServletResponse;"));
			sList.add(new Statement(9000L,0,"import jakarta.servlet.http.HttpServletRequest;"));
			sList.add(new Statement(10000L,0,"import jakarta.servlet.http.HttpServletResponse;"));
		} else {
			sList.add(new Statement(7000L,0,"import javax.servlet.ServletRequest;"));
			sList.add(new Statement(8000L,0,"import javax.servlet.ServletResponse;"));
			sList.add(new Statement(9000L,0,"import javax.servlet.http.HttpServletRequest;"));
			sList.add(new Statement(10000L,0,"import javax.servlet.http.HttpServletResponse;"));
		}
		sList.add(new Statement(11000L,0,""));
		sList.add(new Statement(12000L,0,"import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;"));
		sList.add(new Statement(13000L,0,"import org.slf4j.Logger;"));
		sList.add(new Statement(14000L,0,"import org.slf4j.LoggerFactory;"));
		sList.add(new Statement(15000L,0,""));
		sList.add(new Statement(16000L,0,"import com.alibaba.fastjson.JSON;"));
		sList.add(new Statement(17000L,0,""));
		sList.add(new Statement(18000L,0,"/**"));
		sList.add(new Statement(19000L,0,"* @author by. 不笑猫丶"));
		sList.add(new Statement(20000L,0,"* @date 2018年12月12日"));
		sList.add(new Statement(21000L,0,"*/"));
		sList.add(new Statement(22000L,0,"public class ShiroAuthFilter extends FormAuthenticationFilter {"));
		sList.add(new Statement(23000L,0,""));
		sList.add(new Statement(24000L,1,"private static final Logger logger = LoggerFactory.getLogger(ShiroAuthFilter.class);"));
		sList.add(new Statement(25000L,0,""));
		sList.add(new Statement(26000L,0,""));
		sList.add(new Statement(27000L,1,"public ShiroAuthFilter() {"));
		sList.add(new Statement(28000L,2,"super();"));
		sList.add(new Statement(29000L,1,"}"));
		sList.add(new Statement(30000L,0,""));
		sList.add(new Statement(31000L,1,"@Override"));
		sList.add(new Statement(32000L,1,"public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {"));
		sList.add(new Statement(33000L,2,"//Always return true if the request's method is OPTIONS"));
		sList.add(new Statement(34000L,2,"if (request instanceof HttpServletRequest) {"));
		sList.add(new Statement(35000L,3,"if (((HttpServletRequest) request).getMethod().toUpperCase().equals(\"OPTIONS\")) {"));
		sList.add(new Statement(36000L,4,"return true;"));
		sList.add(new Statement(37000L,3,"}"));
		sList.add(new Statement(38000L,2,"}"));
		sList.add(new Statement(39000L,2,"return super.isAccessAllowed(request, response, mappedValue);"));
		sList.add(new Statement(40000L,1,"}"));
		sList.add(new Statement(41000L,0,""));
		sList.add(new Statement(42000L,1,"@Override"));
		sList.add(new Statement(43000L,1,"protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {"));
		sList.add(new Statement(44000L,2,"logger.info(\"SHIROFILTER authc拦截\");"));
		sList.add(new Statement(45000L,2,"HttpServletResponse res = (HttpServletResponse)response;"));
		sList.add(new Statement(46000L,2,"res.setHeader(\"Access-Control-Allow-Origin\", \"true\");"));
		sList.add(new Statement(47000L,2,"res.setContentType(\"application/json; charset=utf-8\");"));
		sList.add(new Statement(48000L,2,"res.setStatus(HttpServletResponse.SC_OK);"));
		sList.add(new Statement(49000L,2,"PrintWriter writer = res.getWriter();"));
		sList.add(new Statement(50000L,2,"Map<String, Object> map= new HashMap<>();"));
		sList.add(new Statement(51000L,2,"map.put(\"status\", 3);"));
		sList.add(new Statement(52000L,2,"map.put(\"msg\", \"未登录\");"));
		sList.add(new Statement(53000L,2,"writer.write(JSON.toJSONString(map));"));
		sList.add(new Statement(54000L,2,"writer.close();"));
		sList.add(new Statement(55000L,2,"//return false 拦截， true 放行"));
		sList.add(new Statement(56000L,2,"return false;"));
		sList.add(new Statement(57000L,1,"}"));
		sList.add(new Statement(58000L,0,"}"));
		
		return sList.getContent();
	}
	
	public String getTranslateRefers(Set<Domain> targets,Domain domain) {
		Map<Domain,Set<Domain>> tanslateReferMap = new TreeMap<>();
		for (Domain target:targets) {
			for (Field f: target.getFields()) {
				if (f instanceof Dropdown) {
					Dropdown dp = (Dropdown)f;
					if (!target.getStandardName().equals(dp.getTarget())) {
						Set<Domain> refers = tanslateReferMap.get(dp.getTarget());
						if (refers == null) refers= new TreeSet<Domain>();					
						refers.add(target);
						tanslateReferMap.put(dp.getTarget(), refers);	
					}
				}
			}
		}
		Set<Domain> retVal = tanslateReferMap.get(domain);
		String retstr = "";
		if (retVal!=null) {
			retVal.remove(domain);
			for (Domain d:retVal) {
				retstr = retstr + d.getStandardName()+",";
			}
		}
		if (retstr.contains(",")) retstr = retstr.substring(0,retstr.length()-1);
		return retstr;
	}

}
